package com.wei.czz.common.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.Duration;
import java.util.Objects;

/**
 * Created by IntelliJ IDEA.
 *
 * @author wyw
 * date: 2024-04-20 19:41:22
 * className: GuavaManager
 * version: 1.0
 * description:
 */
public class GuavaUtils {

    private static final Logger log = LoggerFactory.getLogger(GuavaUtils.class);

    /**
     * 缓存时长（五分钟）
     */
    public static final Integer CACHE_MILLIS = 5 * 60 * 1000;

    /**
     * guava本地缓存对象
     * 初始化容量：100
     * 最大缓存个数：1000
     * 缓存过期时间：5分钟
     */
    private static final LoadingCache<String, String> localCache = CacheBuilder.newBuilder()
            .initialCapacity(100)
            .maximumSize(1000)
            .expireAfterWrite(Duration.ofMillis(CACHE_MILLIS))
            .build(new CacheLoader<String, String>() {
                @Override
                public String load(String key) throws Exception {
                    log.info("本地缓存不存在。key={}", key);
                    return "";
                }
            });

    private static final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 设置缓存
     * @param key   缓存键
     * @param value 缓存值
     * @param <T>   泛型类型
     */
    public static <T> void set(String key, T value) {
        if (Objects.isNull(key) || Objects.isNull(value)) {
            log.info("设置本地缓存参数存在空值。key={} value={}", key, value);
            return;
        }
        String cacheValue;
        if (value instanceof String) {
            cacheValue = (String) value;
        } else {
            try {
                cacheValue = objectMapper.writeValueAsString(value);
            } catch (JsonProcessingException e) {
                log.error("本地缓存值序列化异常。value={} message={}", value, e.getMessage(), e);
                return;
            }
        }
        localCache.put(key, cacheValue);
    }

    /**
     * 获取缓存
     * @param key 缓存键
     * @return 缓存值
     */
    public static String get(String key) {
        try {
            return localCache.get(key);
        } catch (Exception e) {
            log.warn("获取本地缓存异常。key={} exception={} message={}", key, e.getClass().getSimpleName(), e.getMessage());
            return null;
        }
    }

    /**
     * 获取缓存
     * @param key 缓存键
     * @param <T> 泛型类型
     * @return 缓存值
     */
    public static <T> T get(String key, Class<T> clazz) {
        String cacheValue = get(key);
        if (cacheValue == null || cacheValue.isEmpty()) {
            return null;
        }
        try {
            return objectMapper.readValue(cacheValue, clazz);
        } catch (Exception e) {
            log.warn("本地缓存反序列化异常。key={} exception={} message={}", key, e.getClass().getSimpleName(),
                    e.getMessage());
            return null;
        }
    }

    /**
     * 获取缓存
     * @param key 缓存键
     * @param <T> 泛型类型
     * @return 缓存值
     */
    public static <T> T get(String key, TypeReference<T> typeReference) {
        String cacheValue = get(key);
        if (cacheValue == null || cacheValue.isEmpty()) {
            return null;
        }
        try {
            return objectMapper.readValue(cacheValue, typeReference);
        } catch (Exception e) {
            log.warn("本地缓存自定义反序列化异常。key={} exception={} message={}", key, e.getClass().getSimpleName(),
                    e.getMessage());
            return null;
        }
    }

    /**
     * 删除缓存
     * @param key 缓存键
     */
    public static void remove(String key) {
        localCache.invalidate(key);
    }

}
